package com.xiaohao.springbootadmintemplate.filter;

import com.xiaohao.springbootadmintemplate.config.securitycontext.UserDetailsServiceImpl;
import com.xiaohao.springbootadmintemplate.util.JwtTokenUtil;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

//该过滤器只拦截/login，也就是登录验证拦截器
public class SecurityUsernamePasswordContextFilter extends UsernamePasswordAuthenticationFilter {
    //加载用户的Service
    private UserDetailsServiceImpl userDetailsService;
    //安全管理器
    private AuthenticationManager authenticationManager;
    public SecurityUsernamePasswordContextFilter(AuthenticationManager authenticationManager,UserDetailsServiceImpl userDetailsService) {
        this.authenticationManager=authenticationManager;
        this.userDetailsService = userDetailsService;
    }
    @Override
    //验证用户的合法性
    public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response)
            throws AuthenticationException {
        //根据表单的提交获取用户名
        String username = request.getParameter("username");
        //获取密码
        String password = request.getParameter("password");
        //在数据库中查询用户
        UserDetails userDetails = userDetailsService.loadUserByUsername(username);
        if (userDetails == null) {
            throw new UsernameNotFoundException("找不到该用户");
        }
        //根据用户名以及密码、权限生成凭证
        return authenticationManager.authenticate(
                new UsernamePasswordAuthenticationToken(username, password, userDetails.getAuthorities()));
    }

    @Override
    //验证成功调用
    protected void successfulAuthentication(HttpServletRequest request,
                                            HttpServletResponse response, FilterChain chain,
                                            Authentication auth) throws IOException, ServletException {

        String rememberMe = request.getParameter("rememberMe");

        boolean isRememberMe= rememberMe != null && "true".equals(rememberMe);
        //生成token返回给客户端，客户端每次请求需要携带token验证身份信息
        String token = JwtTokenUtil.createToken(auth.getName(), isRememberMe);
        //token放入响应头里面
        response.setHeader("token", JwtTokenUtil.TOKEN_PREFIX + token);
    }

    @Override
    //验证失败调动
    protected void unsuccessfulAuthentication(HttpServletRequest request, HttpServletResponse response, AuthenticationException failed) throws IOException, ServletException {
        //返回401无权限
        response.setStatus(401);
        response.getWriter().write("fail:" + failed.getMessage());
    }
}
